package svc.elib.analysis;

import java.io.IOException;
import java.util.Iterator;

import jsc.correlation.KendallCorrelation;
import jsc.datastructures.PairedData;

import org.apache.commons.math3.stat.correlation.PearsonsCorrelation;
import org.apache.commons.math3.stat.correlation.SpearmansCorrelation;

import svc.elib.db.Author;
import svc.elib.db.Database;
import svc.elib.socnet.CentralityMetrics;
import svc.elib.socnet.EvolutionarySnapshots;
import svc.elib.socnet.Net;
import svc.elib.socnet.SocConstructor;
import svc.elib.socnet.TrivialComponents;

public class EvolutionOfAuthorMetrics {
	
	private static class CorrValue {
		double scc, pcc, kcc;
		
		public CorrValue(double scc, double pcc, double kcc) {
			this.scc = scc;
			this.pcc = pcc;
			this.kcc = kcc;
		}
		
		public String toString() {
			return scc + "," + pcc + "," + kcc;
		}
		
		public String toStringS() {
			return Double.toString(scc);
		}
	}
	
	private static CorrValue computeCorrelations(double[] seq1, double[] seq2) {
		SpearmansCorrelation sc = new SpearmansCorrelation();
		double scc = sc.correlation(seq1, seq2);
		
		PearsonsCorrelation pc = new PearsonsCorrelation();
		double pcc = pc.correlation(seq1, seq2);
		
		KendallCorrelation kc = new KendallCorrelation(new PairedData(seq1, seq2));
		double kcc = kc.getTestStatistic();
		
		return new CorrValue(scc, pcc, kcc);
	}
	
	private static double spearman(double[] seq1, double seq2[]) {
		SpearmansCorrelation sc = new SpearmansCorrelation();
		return sc.correlation(seq1, seq2);
	}
	
	public static void analysis(Net net) {
		EvolutionarySnapshots es = new EvolutionarySnapshots(net);
		int startYear = es.getStartYear();
		Net[] snaps = es.getSnapshots();
				
		for (int i = 0; i < snaps.length; i++) {
			Net cSnap = snaps[i];
			int year = startYear + i;
			
			if (cSnap.getNumNodes() < 2)
				continue;
			
			CentralityMetrics cm = new CentralityMetrics(cSnap);
			cm.computeBetweeness(false);
			
			double seqPapers[] = new double[cSnap.getNumNodes()];
			double seqActivity[] = new double[cSnap.getNumNodes()];
			double seqDegree[] = new double[cSnap.getNumNodes()];
			double seqBet[] = new double[cSnap.getNumNodes()];
			double seqCC[] = new double[cSnap.getNumNodes()];
			
			int scnt = 0;
			
			Iterator<Author> ait = cSnap.getGraph().getVertices().iterator();
			while (ait.hasNext()) {
				Author a = ait.next();
				
				int numPapers = a.getNumPapers();
				int activity = a.getActivitySpan();
				int degree = cSnap.getGraph().degree(a);
				double bet = cm.getBetweenness(a.getName());
				double cc = cSnap.getCC(a);
				
				seqPapers[scnt] = numPapers;
				seqActivity[scnt] = activity;
				seqDegree[scnt] = degree;
				seqBet[scnt] = bet;
				seqCC[scnt] = cc;
				
				++scnt;
			}
			
			CorrValue papers_activity = computeCorrelations(seqPapers, seqActivity);
			CorrValue papers_degree = computeCorrelations(seqPapers, seqDegree);
			CorrValue papers_bet = computeCorrelations(seqPapers, seqBet);
			CorrValue activity_degree = computeCorrelations(seqActivity, seqDegree);
			CorrValue activity_bet = computeCorrelations(seqActivity, seqBet);
			CorrValue degree_bet = computeCorrelations(seqDegree, seqActivity);
			
			CorrValue papers_cc = computeCorrelations(seqPapers,seqCC);
			CorrValue activity_cc = computeCorrelations(seqActivity, seqCC);
			CorrValue degree_cc = computeCorrelations(seqDegree, seqCC);
			CorrValue bet_cc = computeCorrelations(seqBet, seqCC);
			
			//System.out.println(year + "," + papers_activity.toStringS() + "," + papers_degree.toStringS() + "," + papers_bet.toStringS() + ","
			//		          + activity_degree.toStringS() + "," + activity_bet.toStringS() + "," + degree_bet.toStringS());
		
			System.out.println(year + "," + papers_cc.toStringS() + "," + activity_cc.toStringS() + "," + degree_cc.toStringS() + "," + bet_cc.toStringS());
		}
	}
	
	public static void analysis2(Net net) {
		EvolutionarySnapshots es = new EvolutionarySnapshots(net);
		int startYear = es.getStartYear();
		Net[] snaps = es.getSnapshots();
				
		for (int i = 0; i < snaps.length; i++) {
			Net cSnap = snaps[i];
			int year = startYear + i;
			
			if (cSnap.getNumNodes() < 2)
				continue;
			
			CentralityMetrics cm = new CentralityMetrics(cSnap);
			cm.computeBetweeness(false);
			double seqDegree[] = new double[cSnap.getNumNodes()];
			double seqBet[] = new double[cSnap.getNumNodes()];
			double seqCC[] = new double[cSnap.getNumNodes()];
			
			int scnt = 0;
			
			Iterator<Author> ait = cSnap.getGraph().getVertices().iterator();
			while (ait.hasNext()) {
				Author a = ait.next();
				
				int degree = cSnap.getGraph().degree(a);
				double bet = cm.getBetweenness(a.getName());
				double cc = cSnap.getCC(a);
				
				seqDegree[scnt] = degree;
				seqBet[scnt] = bet;
				seqCC[scnt] = cc;
				
				++scnt;
			}
			
			CorrValue degree_bet = computeCorrelations(seqDegree, seqBet);
			CorrValue degree_cc = computeCorrelations(seqDegree, seqCC);
			CorrValue bet_cc = computeCorrelations(seqBet, seqCC);
			
			System.out.println(year + "," + cSnap.getNumNodes() + "," + scnt + "," + degree_bet.toStringS() + "," + degree_cc.toStringS() + "," + bet_cc.toStringS());
		}
	}
	
	public static void analysis3(Net net) {
		
		TrivialComponents tc = new TrivialComponents(net);
		tc.determine();
		tc.filter();
		
		EvolutionarySnapshots es = new EvolutionarySnapshots(net);
		int startYear = es.getStartYear();
		Net[] snaps = es.getSnapshots();
				
		for (int i = 0; i < snaps.length; i++) {
			Net cSnap = snaps[i];
			int year = startYear + i;
			
			if (cSnap.getNumNodes() < 2)
				continue;
			
			CentralityMetrics cm = new CentralityMetrics(cSnap);
			cm.computeBetweeness(false);
			
			double seqDegree[] = new double[cSnap.getNumNodes()];
			double seqBet[] = new double[cSnap.getNumNodes()];
			double seqNumPapers[] = new double[cSnap.getNumNodes()];
			double seqTimeSpan[] = new double[cSnap.getNumNodes()];
			
			int scnt = 0;
			
			Iterator<Author> ait = cSnap.getGraph().getVertices().iterator();
			while (ait.hasNext()) {
				Author a = ait.next();
				
				int degree = cSnap.getGraph().degree(a);
				double bet = cm.getBetweenness(a.getName());
				
				seqDegree[scnt] = degree;
				seqBet[scnt] = bet;
				seqNumPapers[scnt] = a.getNumPapers(year);
				seqTimeSpan[scnt] = a.getLastYear(year) - a.getFirstYear() + 1;
				
				++scnt;
			}
			
			double degree_papers = spearman(seqDegree, seqNumPapers);
			double degree_time = spearman(seqDegree, seqTimeSpan);
			double bet_papers = spearman(seqBet, seqNumPapers);
			double bet_time = spearman(seqBet, seqTimeSpan);
			double papers_time = spearman(seqNumPapers, seqTimeSpan);
			
			System.out.println(year + ", " + degree_papers + ", " + bet_papers + ", " + degree_time + ", " + bet_time + ", " + papers_time);
		}
	}
	
	public static void main(String[] args) 
		throws IOException
	{
		Database db = new Database("eLibData.csv", 1932, 2011);
		SocConstructor soc = new SocConstructor(db);
		Net net = soc.getNet();
		//analysis(net);
		//analysis2(net);
	
		analysis3(net);
	}
	
}
 